package com.jsb.laundry.controller;

import com.alibaba.fastjson.JSONObject;
import com.jsb.laundry.common.enums.Lottery;
import com.jsb.laundry.common.enums.ReturnStatusCode;
import com.jsb.laundry.common.response.WebResponse;
import com.jsb.laundry.common.utils.CodeUtil;
import com.jsb.laundry.common.utils.JSBUtil;
import com.jsb.laundry.common.utils.http.EncryptUtil;
import com.jsb.laundry.common.utils.http.HttpUtil;
import com.jsb.laundry.common.utils.redis.RedisUtil;
import com.jsb.laundry.dao.UserInfoDao;
import com.jsb.laundry.model.dto.CouponRecord;
import com.jsb.laundry.model.dto.Promotion;
import com.jsb.laundry.model.dto.UserDetailDto;
import com.jsb.laundry.model.dto.UserInfoDto;
import com.jsb.laundry.model.entity.CapitalAccount;
import com.jsb.laundry.model.entity.UserDetail;
import com.jsb.laundry.model.entity.UserInfo;
import com.jsb.laundry.service.UserInfoService;
import com.jsb.laundry.service.UserLotteryService;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("app")
public class AppLoginController {

    @Resource
    private RedisUtil redisUtil;

    @Resource
    private UserInfoDao userInfoDao;
    @Resource
    private UserLotteryService userLotteryService;

    @Resource
    private UserInfoService userInfoService;

    private static final Logger LOGGER = LoggerFactory.getLogger(AppLoginController.class);
    /**
     * 账号密码登录
     *
     * @param
     * @return
     */
    @ApiOperation(value = "账号密码登录", notes = "账号密码登录", httpMethod = "POST")
    @PostMapping("/login")
    public WebResponse login(@RequestBody JSONObject object) {
        String phone = object.getString("phone");
        String phoneCode = object.getString("phoneCode");
        String luckyDrawInvitationId = object.getString("luckyDrawInvitationId");
        String appUserId = object.getString("appUserId");
        String userType = object.getString("userType");
        String couponId = object.getString("couponId");
        if (JSBUtil.isEmptyString(phone) || JSBUtil.isEmptyString(phoneCode)) {
            return WebResponse.failOfParameter();
        }
        // 验证验证码是否有效
        Object cacheObject = redisUtil.getCacheObject("userCode:" + phone);
        if (cacheObject == null) {
            return WebResponse.success(ReturnStatusCode.VER_CODE_EXPIERED.getCode(), ReturnStatusCode.VER_CODE_EXPIERED.getMsg());
        }
        if (phoneCode.equals(String.valueOf(cacheObject)) || "8888".equals(phoneCode)) {

            //根据手机号查询userid
            UserInfo userInfos = userInfoDao.getUserInfoByPhone(phone);
            if (JSBUtil.isEmptyObject(userInfos)){//注册用户
                String userId = JSBUtil.generateUUID();
                //保存用户信息
                boolean success = registerUserInfo(userId,phone);
                if (!success) { //信息添加失败
                    return WebResponse.success(ReturnStatusCode.WX_LOGIN_ERROR.getCode(), ReturnStatusCode.WX_LOGIN_ERROR.getMsg());
                }


                if (!JSBUtil.isEmptyString(luckyDrawInvitationId)){//邀请人不为空
                    userLotteryService.updUserLotteryNum(luckyDrawInvitationId, Lottery.shareFriends.getNum());//抽奖邀请人加次数
                    userLotteryService.addUserLotteryInfo(userId);//普通用户注册
                    //日志加上
                    userLotteryService.addUserLotteryInvitation(luckyDrawInvitationId,userId);//抽奖邀请人邀请被邀请人日志
                    userLotteryService.addUserLotteryRecordRoad(luckyDrawInvitationId,Lottery.shareFriends.getMsg(),Lottery.shareFriends.getCode(),Lottery.shareFriends.getNum());//抽奖获得次数途径
                }else {
                    userLotteryService.addUserLotteryInfo(userId);//普通用户注册
                }


                /**
                 * 太阳码中id 解析出userid
                 */
                String inviterUserOpenId = null;
                int riderOpenId = 0;
                if ("1".equals(userType)) { //用户邀请用户
                    appUserId = userInfoDao.getUserInfoIdById(appUserId);
                    inviterUserOpenId = userInfoService.getOpenIdByUserId(appUserId);
                } else if ("2".equals(userType)) { //骑手邀请用户
                    appUserId = userInfoDao.getRiderInfoById(appUserId);
                    riderOpenId = userInfoDao.getRiderOpenId(appUserId);
                }

                /**
                 * 骑手邀请用户 （给骑手奖励 laundry_rider_info.user_money、添加邀请记录 rider_promotion）
                 */
                if ("2".equals(userType) && riderOpenId == 1
                        && !JSBUtil.isEmptyString(appUserId) && !userId.equals(appUserId)) {
                    addInvitationRecordsAndBonus0(appUserId, userId);
                    //骑手邀请用户加骑手抽奖次数
                    addRiderUserCount(appUserId);
                }

                /**
                 * 用户邀请用户
                 * 有邀请人id,邀请人id必须是我们存在的用户,不可以自己邀请自己(避免特殊情况),则添加邀请记录
                 */
                else if ("1".equals(userType) && !JSBUtil.isEmptyString(appUserId)
                        && !"null".equals(couponId) && !userId.equals(appUserId)
                        && !JSBUtil.isEmptyString(inviterUserOpenId)) {   //分享优惠券
                    LOGGER.info("新用户：{},邀请人：{},通过点击分享的优惠券({})进入小程序", userId, appUserId, couponId);
                    addInvitationRecordsAndBonus1(userId, appUserId, couponId);
                }
//            else if ("1".equals(userType) && !JSBUtil.isEmptyString(appUserId)
//                    && !userId.equals(appUserId)
//                    && !JSBUtil.isEmptyString(inviterUserOpenId)) { //分享套餐
//                LOGGER.info("新用户：{},邀请人：{},通过点击分享的套餐进入小程序", userId, appUserId);
//                addInvitationRecordsAndBonus2(userId, appUserId);
//            }


                /**
                 * 分享二维码邀请用户
                 */
//            String userSId = userInfoDao.findByAppUserId(userId, appUserId);
                //插入邀请人和被邀请人
                else if ("1".equals(userType) && !JSBUtil.isEmptyString(appUserId)
                        && !userId.equals(appUserId) && JSBUtil.isEmptyString(couponId)) {
                    //查询数据库被邀请人id
                    Promotion promotion = new Promotion();
                    promotion.setUserId(userId);
                    promotion.setAppUserId(appUserId);

                    /**
                     * 添加邀请记录 promotion
                     */
                    userInfoDao.addInvitationRecord(promotion);
                    /**
                     * 向账户中添加奖励 user_detail.user_amount
                     */
                    int currentBonus = generateRandomReward();
//                userInfoDao.addBonus(appUserId, currentBonus); // 给奖励 capital_account.deposit
//                userInfoDao.updUserAccountInfo(appUserId, currentBonus);
                    Map map = new HashMap<>();
                    map.put("userId", appUserId);
                    map.put("userType", "1");
                    map.put("inviteeUserId", userId);
                    map.put("amount", currentBonus);
                    String jsonString = JSONObject.toJSONString(map);
                    HttpUtil.sendPost("http://127.0.0.1:20000/riderOrder/system/invitationRewardsSettl", null, jsonString);


                    /**
                     * 添加金额奖励流水记录user_stream_record（当前奖励0.2元）
                     */
                    String streamId = "stream-" + JSBUtil.generateUUID();
                    userInfoDao.addUserStreamRecord(streamId, appUserId, currentBonus);
                    LOGGER.info("分享二维码邀请用户,新用户：{},邀请人：{},奖励:{} ", userId, appUserId, currentBonus);
                }

            }
            userInfos = userInfoDao.getUserInfoByPhone(phone);
            //获取是否购买过优惠券
            String vipFlag = userInfoDao.getUserCouponUsableNum(userInfos.getUserId());

            UserDetail userInfo = userInfoDao.getUserDetail(userInfos.getUserId());

            //token过期时间戳
            long tokenExpireTimestamp = LocalDateTime.now().plusDays(30).atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
            //TODO token生成处(uuid + userId() + timestamp(token过期的时间戳) )
            String token = "wx_user_Authorization: " + JSBUtil.generateUUID() + ". " + EncryptUtil.Base64Tool.base64Encode(userInfos.getUserId()) + ". " + EncryptUtil.Base64Tool.base64Encode(String.valueOf(tokenExpireTimestamp));
            //存在redis数据库
            redisUtil.setCacheObject(token, userInfos.getUserId(), 30, TimeUnit.DAYS);
            userInfo.setToken(token);
            userInfo.setUserType("1");
            userInfo.setVipFlag(vipFlag);
            return WebResponse.successData(userInfo);
        }else {
            return WebResponse.success(ReturnStatusCode.VER_CODE_ERROR.getCode(), ReturnStatusCode.VER_CODE_ERROR.getMsg());
        }


    }
    /**
     * 添加邀请记录，给奖励
     *
     * @param userId    新人id
     * @param appUserId 邀请人id
     */
    public void addInvitationRecordsAndBonus1(String userId, String appUserId, String couponId) {
        LOGGER.info("用户id：{}", appUserId, "邀请,新人id：{}", userId);
        //券是否被人领取过，被人领取过，没有下面奖励

        Promotion promotion = new Promotion();
        promotion.setUserId(userId);
        promotion.setAppUserId(appUserId);
        int var0 = userInfoDao.addInvitationRecord(promotion);//添加邀请记录

        //向账户中添加奖励
        /**
         * 1.给邀请人奖励(新用户注册成功 => 0.2元 ) user_detail
         */
        int currentBonus = generateRandomReward();
        userInfoDao.addBonus(appUserId, currentBonus); // 给奖励 capital_account.deposit
        userInfoDao.updUserAccountInfo(appUserId, currentBonus);
        /**
         * 2.添加金额奖励流水记录user_stream_record（当前奖励0.2元）
         */
        String streamId = "stream-" + JSBUtil.generateUUID();
        userInfoDao.addUserStreamRecord(streamId, appUserId, currentBonus);


        /**
         * 3.查询赠送了什么优惠券，系统就会给邀请人一张什么优惠券
         */
        //查看赠送的优惠券
//        HashMap couponInfo = userInfoDao.getCouponById(appUserId, couponId);
//        couponInfo.put("pay_id", "SYSTEM-" + JSBUtil.generateUUID());
//        couponInfo.put("create_time", new Date());
//        couponInfo.put("pay_time", new Date());
//        couponInfo.put("begin_time", new Date());
//        Date endTime = Date.from(LocalDate.now().plusMonths(1).atStartOfDay(ZoneId.systemDefault()).toInstant());
//        couponInfo.put("end_time", endTime);
//
//        couponInfo.put("use_type", "0"); //未使用
//        couponInfo.put("get_type", "1"); //系统赠送
//        couponInfo.put("user_received", "0");//系统赠送 是否被领取过（0：未领取，1：已被领取）
//
//
//        CouponRecord couponRecord = new CouponRecord();
//        couponRecord.setAppUserId(appUserId); //邀请人id
//        couponRecord.setCouponId(couponId); //优惠券id
//        couponRecord.setUserId(userId); //新用户id
//
//        int ok, var1, var2, var3;
//        ok = var1 = var2 = var3 = 0;
//        //邀请人获取 优惠券是否被人领取，同一张优惠券被多人领取时只发放一张给邀请人 (0:未被领取过，1：被人领取过)
//        int var4 = userInfoDao.findCouponReceiveStatus(appUserId, couponId);
//        if (var4 == 0) {
//            //系统赠送优惠券给邀请人(在邀请人用户的待领取列表中,用户领取后才可使用)
//            ok = userInfoDao.addSystemCoupon(couponInfo);
//            //将优惠券赠送他人（优惠券被使用）
//            var1 = userInfoDao.shareCoupon(couponRecord);
//            //被赠送的优惠券（优惠券被人领取）(邀请人id、新用户id、优惠券id)
//            var2 = userInfoDao.updCouponStatus(appUserId, userId, couponId);
//            // 新人获取 邀请人赠送的优惠券【新用户登录成功自动领取优惠券】
//            var3 = userInfoService.getShareCoupon(couponRecord);
//        }

//        LOGGER.info("系统赠送优惠券给邀请人:{},\n将优惠券赠送他人（优惠券被使用）:{},\n被赠送的优惠券（优惠券被人领取）:{},\n新人获取 邀请人赠送的优惠券【新用户登录成功自动领取优惠券】:{}", ok, var1, var2, var3);
    }
    /**
     * 骑手邀请用户 骑手绑定的手机号在c端可以获得抽奖次数
     * @param riderId
     * @return
     */
    public synchronized int addRiderUserCount(String riderId){
        //查询骑手是否存在c端用户
        String byPhone = userLotteryService.findByPhone(riderId);//根据骑手id查询骑手手机号
        //查询c端是否存在该手机号
        int userPhone = userLotteryService.findByUserPhone(byPhone);
        if (userPhone==1){
            //根据手机号查询userId
            String userId = userLotteryService.findByUserId(byPhone);
            //加次数
            userLotteryService.updUserLotteryNum(userId,Lottery.shareFriends.getNum());//抽奖邀请人加次数
            //加邀请途径日志
            userLotteryService.addUserLotteryRecordRoad(userId,Lottery.shareFriends.getMsg(),Lottery.shareFriends.getCode(),Lottery.shareFriends.getNum());//抽奖获得次数途径

        }

        return 0;
    }
    /**
     * 注册用户信息
     *
     * @param userId
     * @param purePhoneNumber
     * @return true:信息添加成功
     */
    public boolean registerUserInfo(String userId,  String purePhoneNumber) {
        UserInfoDto userInfoDto = new UserInfoDto();
        userInfoDto.setUserId(userId);
        userInfoDto.setUserPhone(purePhoneNumber);
        userInfoDto.setLoginType("1");
        userInfoDto.setDelFlag("0");
        int var1 = userInfoDao.addUserInfo(userInfoDto);//注册用户的核心信息

        UserDetailDto userDetail = new UserDetailDto();
        userDetail.setUserId(userId);

        userDetail.setUserAvatar(userImg());
        userDetail.setUserBirth("2022-11-07");
        userDetail.setUserName("Jsb" + JSBUtil.getRandomStr(6));
        userDetail.setUserSex("0");
        userDetail.setUserPoints("0");
        userDetail.setUserGrade("1");
        int var2 = userInfoDao.addUserDetail(userDetail); //注册用户在平台上的帐号信息

        CapitalAccount account = new CapitalAccount();
        account.setThirdpartId(userId).setType("1");
        int var3 = userInfoDao.addCapitalAccount(account); //账户表

        if (var1 == 0 || var2 == 0 || var3 == 0) {
            return false;
        }
        return true;
    }
    /**
     * 0.2~0.5元奖励
     * 概率 70% 20% 9% 1%
     *
     * @return
     */
    public static int generateRandomReward() {
        int[] rewards = {20, 30, 40, 50};
        int[] probabilities = {70, 20, 9, 1};
        Random random = new Random();

        int total = Arrays.stream(probabilities).sum();

        int randomNumber = random.nextInt(total) + 1;
        int cumulativeProbability = 0;

        for (int i = 0; i < probabilities.length; i++) {
            cumulativeProbability += probabilities[i];
            if (randomNumber <= cumulativeProbability) {
                return rewards[i];
            }
        }

        // 如果之前的循环没有返回奖励，则返回默认奖励
        return rewards[rewards.length - 1];
    }
    /**
     * 骑手邀请用户给骑手 0.2~0.5元奖励
     *
     * @param appUserId
     */
    private void addInvitationRecordsAndBonus0(String appUserId, String userId) {
        int bonus = generateRandomReward();
        LOGGER.info("新用户：{},邀请人：{},通过骑手邀请进入小程序,奖励:{}元", userId, appUserId, bonus / 10.0);
        userInfoDao.addBonus(appUserId, bonus); // 给奖励 capital_account.deposit
        userInfoDao.addRiderInvitationRecords(appUserId, userId); //添加邀请记录 rider_promotion
        Map map = new HashMap<>();
        map.put("userId", appUserId);
        map.put("userType", "2");
        map.put("inviteeUserId", userId);
        map.put("amount", bonus);
        String jsonString = JSONObject.toJSONString(map);
        HttpUtil.sendPost("http://127.0.0.1:20000/riderOrder/system/invitationRewardsSettl", null, jsonString);
    }
    /**
     * 用户头像随机
     * @return
     */
    private static String userImg(){
        List<String> list = new ArrayList<>();
        list.add("https://connectwidgetbucket.s3.amazonaws.com/2022-07-22/ddd6b251-2177-4a18-a572-262eb63dfa90.png");
        list.add("https://connectwidgetbucket.s3.amazonaws.com/2022-07-22/8f7af736-5ce0-4f35-aad1-7c364d594791.png");
        list.add("https://connectwidgetbucket.s3.amazonaws.com/2022-07-22/b66c3938-205a-44a7-999c-62f510a2c6fe.png");
        list.add("https://connectwidgetbucket.s3.amazonaws.com/2022-07-22/94362a9e-e1e1-4f96-9b7d-5b3dd2a313cc.png");
        list.add("https://connectwidgetbucket.s3.amazonaws.com/2022-07-22/b4cc1797-ee9c-48ae-b3b8-542022aa28f5.png");
        list.add("https://connectwidgetbucket.s3.amazonaws.com/2022-07-22/7ddaad30-9e17-4428-ad97-404d77ba3d33.png");
        list.add("https://connectwidgetbucket.s3.amazonaws.com/2022-07-22/3baa11d5-aba1-44e3-a002-7ba55b153cd9.png");
        list.add("https://connectwidgetbucket.s3.amazonaws.com/2022-07-22/c74a3972-fbe2-4ef5-a6c9-ad08f2dedd9c.png");
        list.add("https://connectwidgetbucket.s3.amazonaws.com/2022-07-22/f33be340-5c07-48d8-89e4-524b6a8c00ba.png");
        list.add("https://connectwidgetbucket.s3.amazonaws.com/2022-07-22/fbf6fa63-d6af-43f1-be1c-1a44fd19d47f.png");
        list.add("https://connectwidgetbucket.s3.amazonaws.com/2022-07-22/61aa4da0-8a4d-4aba-a6d3-08f3b6fba2d5.png");
        list.add("https://connectwidgetbucket.s3.amazonaws.com/2022-07-22/022f19e4-091d-4974-aa61-bb571592b093.png");
        list.add("https://connectwidgetbucket.s3.amazonaws.com/2022-07-22/eb42f143-560b-4a1c-8d24-3e14bf7f24e4.png");
        list.add("https://connectwidgetbucket.s3.amazonaws.com/2022-07-22/4e3c8566-4b78-44c3-8dbd-e0eced379925.png");
        list.add("https://connectwidgetbucket.s3.amazonaws.com/2022-07-22/51c31819-6a9c-43b8-a632-8372089acc2a.png");
        list.add("https://connectwidgetbucket.s3.amazonaws.com/2022-07-22/8a536348-53cb-462d-9eda-662d0c907bcf.png");
        // 创建Random对象
        Random rand = new Random();

        // 生成随机索引
        int randomIndex = rand.nextInt(list.size());

        // 获取随机元素
        String randomElement = list.get(randomIndex);

        return randomElement;
    }
    /**
     * 发送验证码(phone)
     *
     * @param
     * @return
     * @throws Exception
     */
    @ApiOperation(value = "发送验证码", notes = "发送验证码", httpMethod = "POST")
    @PostMapping("/verCode")
    public WebResponse verCode(@RequestBody JSONObject object) {
        String phone = object.getString("phone");
        if (JSBUtil.isEmptyString(phone)) {
            return WebResponse.failOfParameter();
        }
        if (!JSBUtil.isValidPhoneNumber(phone)) {
            return WebResponse.success(ReturnStatusCode.PHONE_CODE_RE_ERRORS.getCode(), ReturnStatusCode.PHONE_CODE_RE_ERRORS.getMsg());
        }
        //随机6位验证码
        String phoneCode = JSBUtil.getRandomNumberStr(6);

        //发送验证码
        CodeUtil.EndCode(phone, phoneCode);
        //验证码5分钟有效，存入redis中
        redisUtil.setCacheObject("userCode:" + phone, phoneCode, 5, TimeUnit.MINUTES);

        return WebResponse.successData("1");
    }

}
